package com.zhx.common.chat.dao;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhx.common.chat.domain.entity.Contact;
import com.zhx.common.chat.domain.entity.Message;
import com.zhx.common.chat.domain.vo.request.ChatMessageReadReq;
import com.zhx.common.chat.mapper.ContactMapper;
import com.zhx.common.common.domain.vo.req.CursorPageBaseReq;
import com.zhx.common.common.domain.vo.resp.CursorPageBaseResp;
import com.zhx.common.common.util.CursorUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 会话列表 服务实现类
 * </p>
 *
 * @author zhx
 * @since 2024-04-24
 */
@Service
public class ContactDao extends ServiceImpl<ContactMapper, Contact> {

    /**
     * 刷新或创建活跃时间。
     * 该方法用于更新或插入一个聊天室成员的活跃时间记录。
     *
     * @param roomId        聊天室的ID，用于标识具体的聊天室。
     * @param memberUidList 聊天室成员的用户ID列表，表示需要更新活跃时间的成员。
     * @param msgId         消息ID，与具体的活跃时间相关联，用于标识活跃时间是由于哪条消息产生的。
     * @param createTime    活跃时间的创建时间，即成员最后一次活跃的时间点。
     */
    public void refreshOrCreateActiveTime(Long roomId, List<Long> memberUidList, Long msgId, Date createTime) {
        baseMapper.refreshOrCreateActiveTime(roomId, memberUidList, msgId, createTime);
    }

    public Contact get(Long receiveUid, Long roomId) {
        return lambdaQuery()
                .eq(Contact::getUid, receiveUid)
                .eq(Contact::getRoomId, roomId)
                .one();
    }

    public CursorPageBaseResp<Contact> getContactPage(Long uid, CursorPageBaseReq request) {
        return CursorUtils.getCursorPageByMysql(this, request, wrapper -> {
            wrapper.eq(Contact::getUid, uid);
        }, Contact::getActiveTime);
    }

    public List<Contact> getByRoomIds(List<Long> roomIds, Long uid) {
        return lambdaQuery()
                .in(Contact::getRoomId, roomIds)
                .eq(Contact::getUid, uid)
                .list();
    }

    public CursorPageBaseResp<Contact> getReadPage(Message message, ChatMessageReadReq request) {
        return CursorUtils.getCursorPageByMysql(this, request, wrapper -> {
            wrapper.eq(Contact::getRoomId, message.getRoomId());
            wrapper.ne(Contact::getUid, message.getFromUid());
            wrapper.ge(Contact::getReadTime, message.getCreateTime());
        }, Contact::getReadTime);
    }

    public CursorPageBaseResp<Contact> getUnReadPage(Message message, ChatMessageReadReq request) {
        return CursorUtils.getCursorPageByMysql(this, request, wrapper -> {
            wrapper.eq(Contact::getRoomId, message.getRoomId());
            wrapper.ne(Contact::getUid, message.getFromUid());// 不需要查询出自己
            wrapper.lt(Contact::getReadTime, message.getCreateTime());// 已读时间小于消息发送时间
        }, Contact::getReadTime);
    }

    /**
     * 获取指定房间ID的联系人总数。
     *
     * @param roomId 房间ID，用于查询与该房间ID相关的联系人数量。
     * @return 返回该房间ID下的联系人总数，返回类型为Integer。
     */
    public Integer getTotalCount(Long roomId) {
        // 使用Lambda查询方式，根据房间ID查询联系人数量并返回
        return lambdaQuery().eq(Contact::getRoomId,roomId).count();
    }

    // 获取指定消息已读人数
    public Integer getReadCount(Message message) {
        return lambdaQuery()
                .eq(Contact::getRoomId,message.getRoomId())
                .ne(Contact::getUid,message.getFromUid())
                .ge(Contact::getReadTime,message.getCreateTime())
                .count();
    }

    // 根据房间id删除会话
    public Boolean removeByRoomId(Long roomId, List<Long> uidList) {
        if(CollectionUtil.isNotEmpty(uidList)){
            LambdaQueryWrapper<Contact> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Contact::getRoomId,roomId)
                    .in(Contact::getUid,uidList);
            return this.remove(wrapper);
        }
        return false;
    }
}
